package com.jrx.anytxn.transaction.controller.api;


import com.jrx.anytxn.atom.bean.CustBatchSaveBean;
import com.jrx.anytxn.atom.service.IDealCustBatchService;
import com.jrx.anytxn.common.data.TxnRespCode;
import com.jrx.anytxn.common.exception.TxnBizException;
import com.jrx.anytxn.common.exception.TxnException;
import com.jrx.anytxn.customer.constant.CustomerConstant;
import com.jrx.anytxn.customer.entity.CmCustomerFirstLevel;
import com.jrx.anytxn.customer.service.ICustomerService;
import com.jrx.anytxn.i18n.response.TxnRespResult;
import com.jrx.anytxn.param.entity.PrOrganizationTable;
import com.jrx.anytxn.param.service.system.IOrganizationTableService;
import com.jrx.anytxn.redisson.service.RedissonLockService;
import com.jrx.anytxn.redisson.util.LockType;
import com.jrx.anytxn.transaction.constant.TransBizConstant;
import com.jrx.anytxn.transaction.constant.TransErrMsgConstant;
import com.jrx.anytxn.transaction.dto.payment.DealCustBatchReq;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.redisson.api.RLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.concurrent.TimeUnit;

/**
 * 客户日终账户处理
 *
 * @author liuyang
 * @date 2020-09-15
 **/
@Api(tags = "客户日终账户处理相关接口")
@RestController
@RequestMapping(value = "/api/transaction/CustBatch")
public class CustBatchController {

    private static final Logger logger = LoggerFactory.getLogger(CustBatchController.class);

    @Autowired
    private IDealCustBatchService dealCustBatchService;
    @Autowired
    private ICustomerService customerService;
    @Autowired
    private IOrganizationTableService organizationTableService;
    @Autowired
    private RedissonLockService redissonLockService;

    /**
     * 客户日终账户处理
     *
     * @param dealCustBatchReq 客户日终账户处理请求
     * @return TxnRespResult
     * @author liuyang
     * @date 2020-09-15
     */
    @ApiOperation(value = "客户日终账户处理", notes = "客户日终账户处理")
    @PostMapping(value = "/dealCustBatch")
    public TxnRespResult dealCustBatch(@Valid @RequestBody DealCustBatchReq dealCustBatchReq) throws TxnException, InterruptedException {
        // 初始化变量
        TxnRespResult result = new TxnRespResult();
        String customerId = dealCustBatchReq.getCustomerId();
        String organizationId = dealCustBatchReq.getOrganizationId();
        String tenantId = dealCustBatchReq.getTenantId();

        // 获取客户id的redis锁
        logger.info("客户日终账户处理开始:tenantId->{},客户id->{}", tenantId,customerId);
        String lockKey = String.format(TransBizConstant.CUST_BATCH_REDIS_LOCK, tenantId, customerId);
        logger.info("RedissionLock key:{}", lockKey);
        RLock lock = redissonLockService.getRLock(lockKey, LockType.REENTRANT_LOCK);

        try {
            boolean lockFlag = lock.tryLock(CustomerConstant.LOAN_REDIS_LOCK_WAITE_TIME, CustomerConstant.LOAN_REDIS_LOCK_LESS_TIME, TimeUnit.SECONDS);
            if (!lockFlag) {
                String msg = String.format(TransErrMsgConstant.GET_REDIS_LOCK_ERROR, lockKey);
                throw new TxnBizException(TxnRespCode.ERROR.getCode(), msg);
            }
            logger.info("获取到RedissionLock key:{}", lockKey);

            // 获取客户一级信息
            CmCustomerFirstLevel customerFirstLevel = customerService.getFirstLevelByCondition(customerId, organizationId, tenantId);

            // 获取机构信息
            PrOrganizationTable org = organizationTableService.findByOrId(organizationId, tenantId);

            if (!org.getNextProcessingDate().equals(customerFirstLevel.getNextProcessingDate())) {
                // 调用客户原子服务进行日终账户处理
                logger.info("调用客户原子服务进行日终账户处理开始:tenantId->{},客户id->{},orgBusDate->{},custDate->{}",
                        tenantId,customerId,org.getNextProcessingDate(),customerFirstLevel.getNextProcessingDate());
                CustBatchSaveBean custBatchSaveBean = dealCustBatchService.dealCustBatch(customerFirstLevel);

                // 保存日终账户处理信息
                dealCustBatchService.saveCustBean(custBatchSaveBean);
                logger.info("调用客户原子服务进行日终账户处理结束:tenantId->{},客户id->{}", tenantId,customerId);
            }

            logger.info("客户日终账户处理结束:tenantId->{},客户id->{}", tenantId,customerId);
        } finally {
            if(lock.isLocked()) {
                if(lock.isHeldByCurrentThread()) {
                    lock.unlock();
                }
            }
        }

        return result.getSuccess(null);
    }
}
